package com.anlu.base.jdbc.dao;

import com.anlu.base.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Repository("namedParameterUserDaoImpl")
public class NamedParameterUserDaoImpl implements UserDao{

    @Autowired
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Override
    public void insert(User user) {

    }

    @Override
    public void update(User user) {

        Map<String, Object> columnValues = new HashMap<>();
        String tableName = "user";

        StringBuilder sql = new StringBuilder("UPDATE " + tableName + " SET ");

        // 构建 SET 子句(注意列名需要,驼峰转下划线)
        columnValues.forEach((columnName, columnValue) ->
                sql.append(toUnderscore(columnName)).append(" = :").append(columnName).append(", "));

        // 删除最后的逗号和空格
        sql.delete(sql.length() - 2, sql.length());

        sql.append(" WHERE id = :id");

        // 添加 ID 参数
        columnValues.put("id", user.getId());

        // 执行更新操作
        MapSqlParameterSource parameters = buildParameters(columnValues);
        namedParameterJdbcTemplate.update(sql.toString(), parameters);
    }

    @Override
    public List<User> getAll() {
        String tableName = "user";
        String sql = "SELECT * FROM " + tableName;
        return namedParameterJdbcTemplate.queryForList(sql,Map.of())
                .stream()
                //下划线转驼峰
                .map(item -> convertKeysToCamelCase(item))
                .map(item -> {
                    User user = new User();
                    user.setName((String) item.get("name"));
                    user.setAge((Integer) item.get("age"));
                    return user;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<User> getAllByBean() {
        String tableName = "user";
        String sql = "SELECT * FROM " + tableName;

        return namedParameterJdbcTemplate.query(sql,new BeanPropertyRowMapper<User>(User.class));


    }

    @Override
    public User selectOne(Integer id) {
        String sql = "SELECT * FROM user WHERE name = :username ";
        Map<String, Object> params = new HashMap<>();
        params.put("username", "zhang");
        List<User> users = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<>(User.class));
        if(CollectionUtils.isEmpty(users)){
            return null;
        }
        return users.get(0);
    }

    @Override
    public User selectOneM1(Integer id) {
        String tableName = "user";
        String sql = "SELECT * FROM " + tableName +" where id = :id";

        return null;
    }

    @Override
    public User selectOneM2(Integer id) {
        return null;
    }

    @Override
    public User selectOneM3(Integer id) {
        return null;
    }

    @Override
    public User selectOneM4(Integer id) {
        return null;
    }

    @Override
    public Object selectProperty(Integer id) {
        return null;
    }

    private Map<String, Object> convertDataType(Map<String, Object> item) {
        Map<String, Object> convertedItem = new HashMap<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (Map.Entry<String, Object> entry : item.entrySet()) {
            if (entry.getValue() instanceof Date) {
                // 如果值是时间类型，则转换为指定格式的时间字符串
                convertedItem.put(entry.getKey(), dateFormat.format((Date) entry.getValue()));
            } else {
                convertedItem.put(entry.getKey(), entry.getValue());
            }
        }

        return convertedItem;
    }


    private LocalDateTime parseDateTime(String dateTimeString, String dataFormat) {
        return LocalDateTime.parse(dateTimeString, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
    }

    private MapSqlParameterSource buildParameters(Map<String, Object> columnValues) {
        MapSqlParameterSource parameters = new MapSqlParameterSource();
        for (Map.Entry<String, Object> entry : columnValues.entrySet()) {
            if (entry.getValue() instanceof String && isDateString((String) entry.getValue())) {
                // 如果值是时间字符串，则转换为时间对象
                parameters.addValue(entry.getKey(), parseDateString((String) entry.getValue()));
            } else {
                parameters.addValue(entry.getKey(), entry.getValue());
            }
        }
        return parameters;
    }

    private boolean isDateString(String value) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            dateFormat.parse(value);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    private Date parseDateString(String value) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(value);
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid date format: " + value);
        }
    }

    /**
     * 下划线转驼峰
     * @param inputMap
     * @return
     */
    public static Map<String, Object> convertKeysToCamelCase(Map<String, Object> inputMap) {
        Map<String, Object> outputMap = new HashMap<>();
        for (Map.Entry<String, Object> entry : inputMap.entrySet()) {
            String underscoreKey = toCamelCase(entry.getKey());
            outputMap.put(underscoreKey, entry.getValue());
        }
        return outputMap;
    }

    /**
     * 驼峰转下划线
     * @param inputMap
     * @return
     */
    public static Map<String, Object> convertKeysToUnderscore(Map<String, Object> inputMap) {
        Map<String, Object> outputMap = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : inputMap.entrySet()) {
            String underscoreKey = toUnderscore(entry.getKey());
            outputMap.put(underscoreKey, entry.getValue());
        }
        return outputMap;
    }

    /**
     * 将下划线转成驼峰
     * @param s
     * @return
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }

        s = s.toLowerCase();

        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == '_') {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }


    /**
     * 将驼峰命名转换为下划线命名
     */
    public static String toUnderscore(String s) {
        if (s == null) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append("_").append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }
}
